/*
 * SalidaModulo, define la salida para cada sistema
 * individual de cola. Se encuentra como salida del
 * servidor y se encarga de calcular los datos de
 * ro y W
 */

#include "SalidaModulo.h"
#include "Conductor.h"

Define_Module(SalidaModulo);

void SalidaModulo::initialize(){
 nconductoresP=0;
 nconductoresM=0;
 wPractico = 0;
 wauxPractico = 0;
 pPractico = 0;
 pauxPractico = 0;
}

void SalidaModulo::handleMessage(cMessage *msg){
    persona = dynamic_cast<Conductor*> (msg);
    if(strcmp(this->getParentModule()->getName(),"examenPractico")==0)
    	resultadosPractico();
    if(strcmp(this->getParentModule()->getName(),"examenMedico")==0)
      resultadosMedico();
    send(msg,"salida",puertaSalida());
}

/*
 * Calcula W y ro parcialmente para el sistema de cola del examen
 * medico, mostrando los resultados por pantalla
 */
void SalidaModulo::resultadosMedico(){
  nServidoresM = par("nServidores");
  nconductoresM++;
  wauxMedico = wauxMedico + persona->getTSistema().dbl();
  pauxMedico = pauxMedico + persona->getTServidor().dbl();

}

/*
 * Calcula W y ro parcialmente para el sistema de cola del examen
 * practico, mostrando los resultados por pantalla
 */
void SalidaModulo::resultadosPractico(){
  nServidoresP = par("nServidores");
  nconductoresP++;
  wauxPractico = wauxPractico + persona->getTSistema().dbl();
  pauxPractico = pauxPractico + persona->getTServidor().dbl();
}

/*
 * Dadas las probabilidades de que cada conductor
 * se dirija a un sistema de cola en el omnetpp.ini,
 * se define de forma aleatorio hacia que sistema de
 * cola se va dirigir el conductor una vez terminado
 * el tiempo en el sistema de cola actual
 */
int SalidaModulo::puertaSalida(){
	double psalida1 = par("psalida1");
	double psalida2 = par("psalida2");
	double psalida3 = par("psalida3");
	double psalida4 = par("psalida4");
	double aux = (double)rand() / RAND_MAX;
	if((0<aux)&&(aux<psalida1))
	  return 0;
	if((psalida1<=aux)&&(aux < (psalida2+psalida1)))
	  return 1;
	if(((psalida2+psalida1)<=aux)&&(aux < (psalida2+psalida1+psalida3)))
	  return 2;
    if(((psalida2+psalida1+psalida3)<=aux)&&(aux < (psalida2+psalida1+psalida3+psalida4)))
   	  return 3;
    return -1;
}

/*
 * Al finalizar la simulacion se muestran los resultados para W y ro para
 * examenPractico y examenMedico
 */
void SalidaModulo::finish(){
	if(strcmp(this->getParentModule()->getName(),"examenPractico")==0){
        wPractico = wauxPractico/(nconductoresP);
    	ev << "Tiempo Medio en el Sistema = "<< wPractico << "; del Practico \n";

        pPractico = pauxPractico/(nServidoresP*simTime());
		ev << "Utilizacion del servidor = "<< pPractico << "; del Practico \n";
		ev << "\n";
	 }
	if(strcmp(this->getParentModule()->getName(),"examenMedico")==0){
    	wMedico = wauxMedico/nconductoresM;
		ev << "Tiempo Medio en el Sistema = "<< wMedico << "; del Medico \n";

		pMedico = pauxMedico/(simTime()* nServidoresM);
		ev << "Utilizacion del servidor = "<< pMedico << "; del Medico\n";
		ev << "\n";
   }
}

